#include "broadcast.h"
#include "ui_broadcast.h"

#define TOPIC_DATA_DOWN     "/app/data/down"
#define TOPIC_CTL_DOWN      "/app/control/down"

broadcast::broadcast(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::broadcast)
{
    ui->setupUi(this);
    //初始化udpsocket tcpsocket
    udpSocket = new QUdpSocket(this);
    tcpSocket = new QTcpSocket(this);
    timer = new QTimer(this);
    // 设置是否为一次性
    timer->setSingleShot(false);
    //设置触发时间5s
    timer->setInterval(5000);

    //点击搜索为发送广播
    connect(ui->pushButtonsearch,SIGNAL(clicked()),
            this,SLOT(sendBroadcastMessageslot()));
    //点击连接按钮与服务器进行连接
    connect(ui->pushButtonconn,SIGNAL(clicked()),
            this,SLOT(btnConnectSlot()));
    //udpsocket信号来临时将连接按钮改为已连接
    connect(tcpSocket,SIGNAL(connected()),
            this,SLOT(connectSlot()));

    //用户点击 上报模式
    ui->comboBox->setCurrentIndex(1);
    connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(comboxChangedSlot(int)));
}

broadcast::~broadcast()
{
    delete ui;
    delete udpSocket;  // 在析构函数中清理 udpSocket 对象
    if(timer->isActive())
        timer->stop();
    delete timer;
}
QByteArray message =QByteArray("Hello");
//发送广播数据
void broadcast::sendBroadcastMessageslot()
{

    // 设置套接字选项以允许广播
    udpSocket->bind(QHostAddress::AnyIPv4, 0, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
    //广播地址和端口
    QHostAddress broadcastAddress("192.168.31.255");
    quint16 broadcastPort = 8887;
    //发送数据报
    qint64 bytesSent = udpSocket->writeDatagram(message, broadcastAddress, broadcastPort);
    if (bytesSent == -1) {
        qWarning() << "Failed to send broadcast message:" << udpSocket->errorString();
    } else {
        qDebug() << "Broadcast message sent successfully.";
    }
    connect(udpSocket,SIGNAL(readyRead()),
            this,SLOT(readyReadSlot()));
}

void broadcast::readyReadSlot()
{
    while (udpSocket->hasPendingDatagrams()) { // 检查是否有未处理的数据报
        QByteArray datagram; // 创建一个 QByteArray 对象来存储数据报
        datagram.resize(udpSocket->pendingDatagramSize()); // 调整 QByteArray 的大小以适应即将读取的数据报大小

        QHostAddress sender; // 创建一个 QHostAddress 对象来存储发送者的地址
        quint16 senderPort; // 创建一个 quint16 变量来存储发送者的端口号

        udpSocket->readDatagram(datagram.data(), datagram.size(),
                                &sender, &senderPort); // 从 socket 读取数据报，并将发送者的地址和端口号存储到 sender 和 senderPort 中
        QString senderr=sender.toString();
        QString senderPortt=QString::number(senderPort);
        //将接收到的数据在文本框中显示
        ui->textBrowser->append(senderr);
        ui->textBrowser->append(senderPortt);
    }
}

void broadcast::connectSlot()
{
    ui->pushButtonconn->setText("已连接");
    //向服务器发送请求确认服务器是否有点表文件
    //创建一个json并填充数据
    QJsonObject order;
    order["type"]=1;
    //将创建的order转换为QJsonDocument
    QJsonDocument jsonOrder(order);
    //转为json字符串
    QString jsonString=jsonOrder.toJson(QJsonDocument::Indented);
    qDebug()<<jsonString;
    //将json：type1发送给服务器
    QByteArray buffer=jsonString.toUtf8();
    tcpSocket->write(buffer);
    //读取服务器传来的信息
    connect(tcpSocket,SIGNAL(readyRead()),
            this,SLOT(readyReadSlot2()));
}
void broadcast::btnConnectSlot()
{

    QJsonObject jsonObj;
    jsonObj["type"] = 1;
    //jsonObj["type"] = GlobalVal::type;
    jsonObj["limit"] = "all";

    // 将 JSON 对象转换为 QByteArray
    QJsonDocument jsonDoc(jsonObj);
    QByteArray payload = jsonDoc.toJson();


    QMQTT::Message message;
    message.setTopic(TOPIC_DATA_DOWN); //设置主题
    message.setPayload(payload);//负载
    quint16 messageId = GlobalVal::mqtt->publish(message);
    qDebug() << "Message sent with ID:" << messageId;
    GlobalVal::mqtt->detectState();
    GlobalVal::mqtt->doConnected();

    //拿到用户输入的ip和端口号
    QString ip=ui->lineEdit_Ip->text();
    int port=ui->spinBoxPort->value();
    //连接到服务器
    tcpSocket->connectToHost(ip,port);

}
void broadcast::readyReadSlot2()
{
    //读取服务器传来的记录
    QByteArray buff=tcpSocket->readAll();
    QString message = QString::fromUtf8(buff);
    if(message=="i am alive")
    {
        qDebug()<<message;
    }
    //看服务器传来的信息是否需要下发点表若为true则下发点表
    //反序列化服务器传来的json文件，将json字符串解析为QJsonDocument
    QJsonDocument jsonDoc(QJsonDocument::fromJson(buff));
    //将QJsonDocument转换为QJsonObject
    QJsonObject jsonObj=jsonDoc.object();
    //访问数据
    int type=jsonObj["type"].toInt();
    int result=jsonObj["result"].toInt();
    bool up_config=jsonObj["up_config"].toBool();
    qDebug()<<type<<result<<up_config;
    //QString up_config=QString::number(config);
    if(up_config==true)
    {
        //将点表发送给服务器
        QFile file(":/new/prefix1/config.json");
        if(!file.open(QIODevice::ReadOnly|QIODevice::Text))
        {
            qDebug()<<"file open err";
            return;
        }

        QByteArray fileData=file.readAll();
        QString filetext(fileData);

        qDebug()<<filetext;
        tcpSocket->write(fileData);
    }
    if(up_config==false)
    {
        qDebug()<<"upconfig:false";
        connect(timer,SIGNAL(timeout()),
                this,SLOT(timeoutSlot()));
        timer->start();
    }
}

void broadcast::timeoutSlot()
{
    //拥有点表，将type改为3，发送心跳包
    //创建一个json并填充数据
    QJsonObject order;
    order["type"]=3;
    //将创建的order转换为QJsonDocument
    QJsonDocument jsonOrder(order);
    //转为json字符串
    QString jsonString=jsonOrder.toJson(QJsonDocument::Indented);
    //qDebug()<<jsonString;
    //将json：type3发送给服务器
    QByteArray buffer=jsonString.toUtf8();
    tcpSocket->write(buffer);
    //接收服务器传来对心跳包的回复
    //读取服务器传来的记录
    //    QByteArray buff=tcpSocket->readAll();
    //    QString message = QString::fromUtf8(buff);
    //    qDebug()<<message;
}

void broadcast::comboxChangedSlot(int)
{
    // 上报模式
    QJsonObject dataObject;
    QJsonObject jsonObject;
    jsonObject["type"] = 3;
    if(ui->comboBox->currentIndex() == 0) //刷新上报
    {
        GlobalVal::type =0;
        dataObject["type"] = 0;

    }
    if(ui->comboBox->currentIndex() == 1) // 变化上报
    {
        GlobalVal::type =1;
        dataObject["type"] = 1;

    }
    if(ui->comboBox->currentIndex() == 2) // 定时上报
    {
        GlobalVal::type =2;
        dataObject["type"] = 2;
        dataObject["period"] = 5;

    }
    jsonObject["data"] = dataObject;
    QJsonDocument jsonDocument(jsonObject);
    QByteArray payload = jsonDocument.toJson();
    QMQTT::Message message;
    message.setTopic(TOPIC_CTL_DOWN); //设置主题
    message.setPayload(payload);//负载
    GlobalVal::mqtt->publish(message);
}
